package com.engine.kq.biz;

import com.alibaba.fastjson.JSON;
import com.engine.kq.biz.chain.duration.NonDayUnitSplitChain;
import com.engine.kq.biz.chain.duration.NonHalfUnitSplitChain;
import com.engine.kq.biz.chain.duration.NonHourUnitSplitChain;
import com.engine.kq.biz.chain.duration.NonWholeUnitSplitChain;
import com.engine.kq.biz.chain.duration.NonWorkDurationChain;
import com.engine.kq.biz.chain.duration.WorkDayUnitSplitChain;
import com.engine.kq.biz.chain.duration.WorkDurationChain;
import com.engine.kq.biz.chain.duration.WorkHalfUnitSplitChain;
import com.engine.kq.biz.chain.duration.WorkHourUnitSplitChain;
import com.engine.kq.biz.chain.duration.WorkWholeUnitSplitChain;
import com.engine.kq.entity.KQGroupEntity;
import com.engine.kq.entity.TimeScopeEntity;
import com.engine.kq.entity.WorkTimeEntity;
import com.engine.kq.enums.DurationTypeEnum;
import com.engine.kq.enums.FlowReportTypeEnum;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.timer.KQQueue;
import com.engine.kq.timer.KQTaskBean;
import com.engine.kq.wfset.attendance.manager.HrmAttProcSetManager;
import com.engine.kq.wfset.bean.SplitBean;
import com.engine.kq.wfset.util.SplitActionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;
import weaver.workflow.workflow.WorkflowRequestComInfo;

/**
 * 考勤流程action相关数据处理类
 */
public class KQFlowActiontBiz {
  public KQLog kqLog = new KQLog();

  /**
   * 强制收回操作
   * @param requestId
   */
  public void handleDel(int requestId) {
    RecordSet rs = new RecordSet();
    try {
      String updateFreezeSql = "update KQ_ATT_VACATION set status=2 where requestId=?  ";
      boolean isUpdate = rs.executeUpdate(updateFreezeSql,requestId);
    }catch (Exception e){
      e.printStackTrace();
      rs.writeLog("handleDrawBack:删除action报错:"+e.getMessage());
    }
  }
  /**
   * 强制收回操作
   * @param requestId
   * @param workflowId
   */
  public void handleDrawBack(int requestId, int workflowId) {
    kqLog.writeLog("handleDrawBack:进入 强制收回:requestId:"+requestId+":workflowId:"+workflowId);

    RecordSet rs = new RecordSet();
    try {
      String updateFreezeSql = "update KQ_ATT_VACATION set status=2 where requestId=? and workflowId = ? ";
      boolean isUpdate = rs.executeUpdate(updateFreezeSql,requestId,workflowId);
      kqLog.writeLog("handleDrawBack:强制收回isUpdate:"+isUpdate+":updateFreezeSql:"+updateFreezeSql+":requestId:"+requestId+":workflowId:"+workflowId);
    }catch (Exception e){
      e.printStackTrace();
      kqLog.writeLog("handleDrawBack:强制收回action报错:"+e.getMessage());
    }
  }

  /**
   * 强制归档操作
   * @param requestId
   * @param workflowId
   */
  public void handleforceOver(int requestId, int workflowId) {
    RecordSet rs = new RecordSet();
    try {
      String proc_set_sql = "select * from kq_att_proc_set where field001 = ? ";
      rs.executeQuery(proc_set_sql, workflowId);
      if(rs.next()) {
        String proc_set_id = rs.getString("id");
        //得到这个考勤流程设置是否使用明细
        String usedetails = rs.getString("usedetail");
        int kqtype = Util.getIntValue(rs.getString("field006"));
        kqLog.info("handleforceOver:proc_set_id:"+proc_set_id+":kqtype:"+kqtype+":requestId:"+requestId);
        Map<String, String> map = new HashMap<String, String>();
        if(requestId > 0){
          map.put("requestId", "and t.requestId = " + requestId);
        }
        Map<String,String> result = handleKQFlowAction(proc_set_id,usedetails,requestId,kqtype,workflowId,true,false,map);
        if(!result.isEmpty()){
          rs.writeLog("handleforceOver:强制归档action失败:requestId："+requestId+":workflowId:"+workflowId+":proc_set_id:"+proc_set_id);
        }
      }
    }catch (Exception e){
      e.printStackTrace();
      rs.writeLog("handleforceOver:强制归档action报错:"+e.getMessage());
    }
  }

  public Map<String,String> handleKQFlowAction(String proc_set_id, String usedetails, int requestId, int kqtype,
      int workflowId,boolean isForce,boolean isUpgrade,Map<String, String> map) throws Exception{

    Map<String,String> result = new HashMap<>();
    ResourceComInfo rci = new ResourceComInfo();
    List<SplitBean> splitBeans = new ArrayList<SplitBean>();

    DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    //生成处理的sql
    Map<String, String> sqlMap = handleSql(proc_set_id, usedetails, requestId,kqtype,map);
    if(sqlMap != null && !sqlMap.isEmpty()){
      KqSplitFlowTypeEnum flowTypeEnum = null;
      if(kqtype == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){
        result=handleKQLeaveAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.LEAVE;
      }else if(kqtype == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){
        result=handleKQEvectionAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.EVECTION;
      }else if(kqtype == KqSplitFlowTypeEnum.OUT.getFlowtype()){
        result=handleKQOutAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.OUT;
      }else if(kqtype == KqSplitFlowTypeEnum.OVERTIME.getFlowtype()){
        result=handleKQOvertimeAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.OVERTIME;
      }else if(kqtype == KqSplitFlowTypeEnum.SHIFT.getFlowtype()){
        handleKQShiftAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.SHIFT;
      }else if(kqtype == KqSplitFlowTypeEnum.OTHER.getFlowtype()){
        result=handleKQOtherAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.OTHER;
      }else if(kqtype == KqSplitFlowTypeEnum.CARD.getFlowtype()){
        result=handleKQCardAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.CARD;
      }else if(kqtype == KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()){
        result=handleKQLeaveBackAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci);
        flowTypeEnum = KqSplitFlowTypeEnum.LEAVEBACK;
      }else{
        new BaseBean().writeLog("考勤流程没有找到对应类型:proc_set_id:"+proc_set_id+":requestId:"+requestId+":kqtype:"+kqtype);
      }
      if(!result.isEmpty()){
        if(!isUpgrade){
          return result;
        }
      }
      if(!splitBeans.isEmpty() && flowTypeEnum != null){
        if(flowTypeEnum == KqSplitFlowTypeEnum.LEAVEBACK){
          //销假流程需要再拆分下
          handleSplitFLowActionData4LeaveBack(splitBeans,result,isUpgrade,requestId);
          clear_flow_deduct_card(splitBeans,KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()+"",requestId);
        }else if(flowTypeEnum != KqSplitFlowTypeEnum.CARD && flowTypeEnum != KqSplitFlowTypeEnum.SHIFT){
          handleSplitFLowActionData(splitBeans,flowTypeEnum,rci,result,isForce,requestId,workflowId,isUpgrade);
          //流程抵扣打卡
          handle_flow_deduct_card(workflowId,splitBeans,requestId);
        }
      }
    }
    return result;
  }

  /**
   *  流程抵扣打卡逻辑
   * @param workflowId
   * @param splitBeans
   * @param requestId
   */
  public void handle_flow_deduct_card(int workflowId,
      List<SplitBean> splitBeans, int requestId) {
    KQAttProcSetComInfo kqAttProcSetComInfo = new KQAttProcSetComInfo();
    String flow_deduct_card = Util.null2String(kqAttProcSetComInfo.getFlow_deduct_card(""+workflowId));
    String kqType = Util.null2String(kqAttProcSetComInfo.getkqType(""+workflowId));
    kqLog.info("handle_flow_deduct_card:flow_deduct_card:"+ flow_deduct_card+":workflowId:"+workflowId+":requestId:"+requestId);
    if("1".equalsIgnoreCase(flow_deduct_card)){
      do_flow_deduct_card(splitBeans,kqType,requestId);
    }
  }

  /**
   * 销假流程 消除流程抵扣打卡
   * @param splitBeans
   * @param kqType
   * @param requestId
   */
  public void clear_flow_deduct_card(List<SplitBean> splitBeans, String kqType, int requestId) {
    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    List<String> clear_ids = new ArrayList<>();
    List<String> formateList = new ArrayList<>();
    KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo();
    for(SplitBean bean : splitBeans){
      String leavebackrequestid = bean.getLeavebackrequestid();
      String resourceId = bean.getResourceId();
      String belongDate = bean.getBelongDate();
      String fromdate = bean.getFromDate();
      String fromtime = bean.getFromTime();
      String todate = bean.getToDate();
      String totime = bean.getToTime();
      String key = resourceId+"_"+belongDate;
      formateList.add(key);
      int fromtimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(fromtime);
      int totimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(totime);
      String deduct_sql = "select * from kq_flow_deduct_card where requestid = "+leavebackrequestid+" and resourceId="+resourceId;
      rs.executeQuery(deduct_sql);
      while(rs.next()){
        String deduct_id = rs.getString("id");
        String signtype = rs.getString("signtype");
        String deduct_fromtime = rs.getString("fromtime");
        String deduct_totime = rs.getString("totime");
        int deduct_fromtimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(deduct_fromtime);
        int deduct_totimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(deduct_totime);
        if("1".equalsIgnoreCase(signtype)){
          if(fromtimeIdx == deduct_fromtimeIdx){
            clear_ids.add(deduct_id);
          }
        }else if("2".equalsIgnoreCase(signtype)){
          if(totimeIdx == deduct_totimeIdx){
            clear_ids.add(deduct_id);
          }
        }
      }
    }
    if(!clear_ids.isEmpty()){
     for(String id : clear_ids){
       String sql = "update kq_flow_deduct_card set isclear=1 where id = "+id;
       rs1.executeUpdate(sql);
     }
      kqLog.info("clear_flow_deduct_card:formateList:"+formateList);
      for(String format: formateList){
        kqLog.info("clear_flow_deduct_card:format:"+ JSON.toJSONString(format));
        String[] formats = format.split("_");
        new KQFormatBiz().formatDate(formats[0],formats[1]);
      }
    }
  }

  /**
   *  流程抵扣打卡逻辑
   * @param splitBeans
   * @param kqType
   * @param requestId
   */
  public void do_flow_deduct_card(List<SplitBean> splitBeans, String kqType, int requestId) {
    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    KQWorkTime kqWorkTime = new KQWorkTime();
    KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo();
    String batchSql = "insert into kq_flow_deduct_card(requestid,resourceid,belongDate,fromdate,fromtime,todate,totime,workBeginTime,workEndTime,signtype,flowtype,serialnumber)"+
        " values(?,?,?,?,?,?,?,?,?,?,?,?) ";
    List<List> params = new ArrayList<List>();
    List<String> formateList = new ArrayList<>();
    kqLog.info("handle_flow_deduct_card:splitBeans:"+ JSON.toJSONString(splitBeans));
    for(SplitBean bean : splitBeans){
      String resourceId = bean.getResourceId();
      String belongDate = bean.getBelongDate();
      String fromdate = bean.getFromDate();
      String fromtime = bean.getFromTime();
      String todate = bean.getToDate();
      String totime = bean.getToTime();
      WorkTimeEntity workTime = kqWorkTime.getWorkTime(resourceId, belongDate);
      String key = resourceId+"_"+belongDate;
      formateList.add(key);
      List<TimeScopeEntity> lsWorkTime = new ArrayList<>();
      if (workTime != null) {
        lsWorkTime = workTime.getWorkTime();//工作时间
        for (int i = 0; lsWorkTime != null && i < lsWorkTime.size(); i++) {
          TimeScopeEntity workTimeScope = lsWorkTime.get(i);
          String workBeginTime = Util.null2String(workTimeScope.getBeginTime());
          int workBeginIdx = kqTimesArrayComInfo.getArrayindexByTimes(workBeginTime);
          boolean workBenginTimeAcross = workTimeScope.getBeginTimeAcross();
          String workEndTime = Util.null2String(workTimeScope.getEndTime());
          int workEndIdx = kqTimesArrayComInfo.getArrayindexByTimes(workEndTime);
          boolean workEndTimeAcross = workTimeScope.getEndTimeAcross();
          int[] dayMins = new int[2880];//一天所有分钟数
          int beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(fromtime));
          int endIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(totime));
          if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){
            Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7
          }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.OUT.getFlowtype()){
            Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8
          }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){
            if (endIdx > beginIdx) {
              Arrays.fill(dayMins, beginIdx, endIdx, 5);//流程抵扣时段标识 5
            }
          }else{
            if (endIdx > beginIdx) {
              Arrays.fill(dayMins, beginIdx, endIdx, 99);//异常流程抵扣时段标识99
            }
          }

          int cnt_7 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 7);
          int cnt_8 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 8);
          int cnt_5 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 5);
          int cnt_99 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 99);
          //流程时长大于0的才去做流程抵扣的处理
          if(cnt_7 > 0 || cnt_8 > 0 || cnt_5 > 0 || cnt_99 > 0){
            //如果流程时长大于0 结束时间因为是下标，需要补1分钟
            if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){
              Arrays.fill(dayMins, endIdx, endIdx+1, 7);//出差抵扣时段标识 7
            }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.OUT.getFlowtype()){
              Arrays.fill(dayMins, endIdx, endIdx+1, 8);//公出抵扣时段标识 8
            }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){
              Arrays.fill(dayMins, endIdx, endIdx+1, 5);//流程抵扣时段标识 5
            }else{
              Arrays.fill(dayMins, endIdx, endIdx+1, 99);//异常流程抵扣时段标识99
            }

            if(dayMins[workBeginIdx]>=5){//签到时间点有流程
              List<Object> beanParams =  new ArrayList<Object>();
              beanParams.add(requestId);
              beanParams.add(resourceId);
              beanParams.add(belongDate);
              beanParams.add(fromdate);
              beanParams.add(fromtime);
              beanParams.add(todate);
              beanParams.add(totime);
              beanParams.add(workBeginTime);
              beanParams.add(workEndTime);
              beanParams.add("1");
              beanParams.add(kqType);
              beanParams.add(i);
              params.add(beanParams);
            }

            if(dayMins[workEndIdx]>=5){//签退时间点有流程
              List<Object> beanParams =  new ArrayList<Object>();
              beanParams.add(requestId);
              beanParams.add(resourceId);
              beanParams.add(belongDate);
              beanParams.add(fromdate);
              beanParams.add(fromtime);
              beanParams.add(todate);
              beanParams.add(totime);
              beanParams.add(workBeginTime);
              beanParams.add(workEndTime);
              beanParams.add("2");
              beanParams.add(kqType);
              beanParams.add(i);
              params.add(beanParams);
            }
          }else{
            kqLog.info("handle_flow_deduct_card::i:"+i+":workBeginIdx:"+ workBeginIdx+":workEndIdx:"+ workEndIdx
                +":cnt_7:"+cnt_7+":cnt_8:"+cnt_8+":cnt_5:"+cnt_5+":cnt_99:"+cnt_99);
          }
        }
      }else{
        kqLog.info("handle_flow_deduct_card:workTime is null :resourceId:"+ resourceId+":belongDate:"+belongDate);
      }
    }
    if(!params.isEmpty()) {
      //先根据requestid删除中间表里的数据，再做啥插入操作
      String delSql = "delete from kq_flow_deduct_card where requestid = " + requestId;
      rs.executeUpdate(delSql);
      boolean isOk = rs1.executeBatchSql(batchSql, params);
      if(!isOk){
        kqLog.info("do_flow_deduct_card:requestId:"+requestId+":kq_flow_deduct_card error："+params);
        return ;
      }
      kqLog.info("do_flow_deduct_card:formateList:"+formateList);
      for(String format: formateList){
        kqLog.info("do_flow_deduct_card:format:"+ JSON.toJSONString(format));
        String[] formats = format.split("_");
        new KQFormatBiz().formatDate(formats[0],formats[1]);
      }
    }else{
      if(!splitBeans.isEmpty()){
        //有流程数据，但是签到签退都不包含的情况，支持多次归档，所以需要先删除再插入
        String delSql = "delete from kq_flow_deduct_card where requestid = " + requestId;
        rs.executeUpdate(delSql);
      }
    }
  }

  /**
   *
   * @param splitBeans
   * @param result
   * @param isUpgrade 是否是升级，升级的话不需要处理假期余额数据
   * @param requestId
   * @throws Exception
   */
  private void handleSplitFLowActionData4LeaveBack(
      List<SplitBean> splitBeans, Map<String, String> result, boolean isUpgrade, int requestId) throws Exception{

    boolean isBackOk = buildLeaveBackData(splitBeans,requestId);
    if(isBackOk){
      if(!isUpgrade){
        //根据销假数据回填带薪数据
      //  SplitActionUtil.reBuildBalance(splitBeans);
      }

    }else{
      result.put("status", "-1");
      result.put("message", "数据库执行失败:销假拆分数据到中间表保存失败");
      return ;
    }
  }


  /**
   * 销假数据拆分记录
   * @param backsplitBeans
   * @param requestId
   * @return
   */
  private boolean buildLeaveBackData(List<SplitBean> backsplitBeans, int requestId){
    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    RecordSet rs2 = new RecordSet();

    List<String> formateList = new ArrayList<>();
    String backbatchSql = "insert into "+KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" (subcompanyid,departmentid,jobtitle,requestid,workflowid,usedetail,dataid,detailid,resourceid,fromdate,fromtime,todate,totime,newleavetype,durationdb,duration,durationrule,status,belongDate,D_Mins,serialid,tablenamedb,fromdatedb,fromtimedb,todatedb,totimedb,leavebackrequestid)"+
        " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
    List<List> params = new ArrayList<List>();
    List<String> updateSql = new ArrayList<>();

    for(SplitBean bean : backsplitBeans){
      List<Object> beanParams =  new ArrayList<Object>();
      beanParams.add(bean.getSubcompanyid());
      beanParams.add(bean.getDepartmentid());
      beanParams.add(bean.getJobtitle());
      beanParams.add(bean.getRequestId());
      beanParams.add(bean.getWorkflowId());
      beanParams.add(bean.getUsedetail());
      beanParams.add(bean.getDataId());
      beanParams.add(bean.getDetailId());
      beanParams.add(bean.getResourceId());
      beanParams.add(bean.getFromDate());
      beanParams.add(bean.getFromTime());
      beanParams.add(bean.getToDate());
      beanParams.add(bean.getToTime());
      beanParams.add(bean.getNewLeaveType());
      beanParams.add(bean.getDurationDB());
      beanParams.add(Util.null2s(bean.getDuration(),"0"));
      beanParams.add(bean.getDurationrule());
      beanParams.add(bean.getStatus());
      beanParams.add(bean.getBelongDate());
      beanParams.add(bean.getD_Mins());
      beanParams.add(bean.getSerialid());
      beanParams.add(bean.getTablenamedb());
      beanParams.add(bean.getFromdatedb());
      beanParams.add(bean.getFromtimedb());
      beanParams.add(bean.getTodatedb());
      beanParams.add(bean.getTotimedb());
      beanParams.add(bean.getLeavebackrequestid());
      String format = bean.getResourceId()+"_"+bean.getFromDate();
      formateList.add(format);

      params.add(beanParams);

      String updateLeaveSql = "";
      if(rs1.getDBType().equalsIgnoreCase("oracle")&&!Util.null2String(rs1.getOrgindbtype()).equals("dm")&&!Util.null2String(rs1.getOrgindbtype()).equals("st")) {
        updateLeaveSql = "update "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" set leavebackrequestid=nvl(leavebackrequestid,'')||','||"+bean.getRequestId()+" where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"'";
      }else if((rs1.getDBType()).equalsIgnoreCase("mysql")){
        updateLeaveSql = "update "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" set leavebackrequestid=concat(ifnull(leavebackrequestid,''),',',"+bean.getRequestId()+") where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"'";
      }else {
        updateLeaveSql = "update "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" set leavebackrequestid=isnull(leavebackrequestid,'')+',"+bean.getRequestId()+"'"+" where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"'";
      }
      updateSql.add(updateLeaveSql);
    }
    if(!params.isEmpty()){
      //先根据requestid删除中间表里的数据，再做啥插入操作
      String delSql = "delete from "+KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" where requestid = "+requestId;
      rs2.executeUpdate(delSql);
      boolean isOk = rs1.executeBatchSql(backbatchSql, params);
      if(isOk){
        for(String up_sql : updateSql){
          kqLog.info("销假记录sql buildLeaveBackData up_sql:"+up_sql);
          boolean isUpOk = rs.executeUpdate(up_sql);
          kqLog.info("销假记录执行情况 buildLeaveBackData isUpOk:"+isUpOk);
        }
        KQFormatData kqFormatData = new KQFormatData();
        kqLog.info("handleSplitFLowActionData4LeaveBack:formateList:"+formateList);
        for(String format: formateList){
          String[] formats = format.split("_");
          kqLog.info("handleSplitFLowActionData4LeaveBack:formats:"+ JSON.toJSONString(formats));
          new KQFormatBiz().formatDate(formats[0],formats[1]);
        }
        return true;
      }else{
        return false;
      }
    }else{
      return false;
    }
  }

  /**
   * 插入数据到中间表
   * @param splitBeans
   * @param flowTypeEnum
   * @param rci
   * @param result
   * @param isForce
   * @param requestId
   * @param workflowId
   * @param isUpgrade 是否是升级，升级的话不需要处理假期余额数据
   * @throws Exception
   */
  public void handleSplitFLowActionData(
      List<SplitBean> splitBeans, KqSplitFlowTypeEnum flowTypeEnum,
      ResourceComInfo rci, Map<String, String> result, boolean isForce, int requestId,
      int workflowId,boolean isUpgrade) throws Exception{

    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    KQFormatData kqFormatData = new KQFormatData();

    String batchSql = "insert into "+flowTypeEnum.getTablename()+" ("
        + "requestid,workflowid,dataid,detailid,resourceid,fromdate,fromtime,"
        + "todate,totime,newleavetype,duration,usedetail,durationrule,tablenamedb,fromdatedb,"
        + "fromtimedb,todatedb,totimedb,durationdb,status,belongDate,D_Mins,serialid,"
        + "changeType,subcompanyid,departmentid,jobtitle,companion,iscompanion)"+
        " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
    List<List> params = new ArrayList<List>();

    List<String> formateList = new ArrayList<>();
    for(SplitBean bean : splitBeans){
      List<Object> beanParams =  new ArrayList<Object>();
      beanParams.add(bean.getRequestId());
      beanParams.add(bean.getWorkflowId());
      beanParams.add(bean.getDataId());
      beanParams.add(bean.getDetailId());
      beanParams.add(bean.getResourceId());
      beanParams.add(bean.getFromDate());
      beanParams.add(bean.getFromTime());
      beanParams.add(bean.getToDate());
      beanParams.add(bean.getToTime());
      beanParams.add(bean.getNewLeaveType());
      beanParams.add(Util.null2s(bean.getDuration(),"0"));
      beanParams.add(bean.getUsedetail());
      beanParams.add(bean.getDurationrule());
      beanParams.add(bean.getTablenamedb());
      beanParams.add(bean.getFromdatedb());
      beanParams.add(bean.getFromtimedb());
      beanParams.add(bean.getTodatedb());
      beanParams.add(bean.getTotimedb());
      beanParams.add(bean.getDurationDB());
      beanParams.add(bean.getStatus());
      beanParams.add(bean.getBelongDate());
      beanParams.add(bean.getD_Mins());
      beanParams.add(bean.getSerialid());
      beanParams.add(bean.getChangeType());
      beanParams.add(bean.getSubcompanyid());
      beanParams.add(bean.getDepartmentid());
      beanParams.add(bean.getJobtitle());
      beanParams.add(bean.getCompanion());
      beanParams.add("");
      String format = bean.getResourceId()+"_"+bean.getFromDate();
      formateList.add(format);

      params.add(beanParams);

      if(flowTypeEnum == KqSplitFlowTypeEnum.EVECTION){
        String companion = Util.null2s(bean.getCompanion(), "");
        if(companion.length() > 0){
          String[] companions = companion.split(",");
          if(companions != null && companions.length > 0 ) {
            for (int i = 0; i < companions.length; i++) {
              String compan_resid = companions[i];
              if(bean.getResourceId().equalsIgnoreCase(compan_resid)){
                //陪同人是自己的不要存到中间表里
                continue;
              }
              beanParams =  new ArrayList<Object>();
              beanParams.add(bean.getRequestId());
              beanParams.add(bean.getWorkflowId());
              beanParams.add(bean.getDataId());
              beanParams.add(bean.getDetailId());
              beanParams.add(compan_resid);
              beanParams.add(bean.getFromDate());
              beanParams.add(bean.getFromTime());
              beanParams.add(bean.getToDate());
              beanParams.add(bean.getToTime());
              beanParams.add(bean.getNewLeaveType());
              beanParams.add(Util.null2s(bean.getDuration(),"0"));
              beanParams.add(bean.getUsedetail());
              beanParams.add(bean.getDurationrule());
              beanParams.add(bean.getTablenamedb());
              beanParams.add(bean.getFromdatedb());
              beanParams.add(bean.getFromtimedb());
              beanParams.add(bean.getTodatedb());
              beanParams.add(bean.getTotimedb());
              beanParams.add(bean.getDurationDB());
              beanParams.add(bean.getStatus());
              beanParams.add(bean.getBelongDate());
              beanParams.add(bean.getD_Mins());
              beanParams.add(bean.getSerialid());
              beanParams.add(bean.getChangeType());
              beanParams.add(rci.getSubCompanyID(compan_resid));
              beanParams.add(rci.getDepartmentID(compan_resid));
              beanParams.add(rci.getDepartmentID(compan_resid));
              beanParams.add(bean.getCompanion());
              beanParams.add("1");
              String format_1 = compan_resid+"_"+bean.getFromDate();
              formateList.add(format_1);
              params.add(beanParams);
            }
          }
        }
      }
    }
    if(!params.isEmpty()){
      //先根据requestid删除中间表里的数据，再做啥插入操作
      String delSql = "delete from "+flowTypeEnum.getTablename()+" where requestid = "+requestId;
      rs.executeUpdate(delSql);

      boolean isOk = rs1.executeBatchSql(batchSql, params);
      if(!isOk){
        result.put("status", "-1");
        result.put("message", "数据库执行失败:"+flowTypeEnum.getTablename()+"拆分保存失败");
        kqLog.info("handleSplitFLowActionData:"+flowTypeEnum.getTablename()+"拆分保存失败："+params);
        return ;
      }
      kqLog.info("handleSplitFLowActionData:formateList:"+formateList+":flowTypeEnum:"+flowTypeEnum);
      for(String format: formateList){
        kqLog.info("handleSplitFLowActionData:format:"+ JSON.toJSONString(format)+":flowTypeEnum:"+flowTypeEnum);
        String[] formats = format.split("_");
        new KQFormatBiz().formatDate(formats[0],formats[1]);
      }
      if(!isUpgrade){
        if(isForce){
          if(flowTypeEnum == KqSplitFlowTypeEnum.LEAVE){
            //先在这里执行扣减动作
            SplitActionUtil.handleLeaveAction(splitBeans,""+requestId);
            //然后再把扣减的了数据更新下KQ_ATT_VACATION表
            String updateFreezeSql = "update KQ_ATT_VACATION set status=0 where requestId=? and workflowId = ? ";
            boolean isUpdate = rs.executeUpdate(updateFreezeSql,requestId,""+workflowId);
            if(!isUpdate){
              result.put("status", "-1");
              result.put("message", ("扣减action保存失败："+updateFreezeSql+"(0,"+requestId+","+workflowId+")"));
              kqLog.info("扣减action保存失败："+updateFreezeSql+"(0,"+requestId+","+workflowId+")");
              return ;
            }
          }else if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){
            // 强制归档，加班数据第一第二种规则都需要处理
            SplitActionUtil.handleOverTimeAction(splitBeans, ""+requestId,true);
          }
        }else{
          if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){
            //正常归档的时候 单独针对加班规则的第二种模式 生成加班数据
            SplitActionUtil.handleOverTimeActionMode2(splitBeans, ""+requestId);
          }
        }
      }
    }else{
      rs1.writeLog(flowTypeEnum.getTablename()+"生成的params是空：");
      return ;
    }
  }

  /**
   * 拆分销假流程数据 生成数据到splitBeans和backsplitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQLeaveBackAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    Map<String,String> result = new HashMap<>();

    RecordSet rs1 = new RecordSet();

    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String key = me.getKey();
        String value = me.getValue();
        String concort = "###" ;
        int usedetail =  Util.getIntValue(key.split(concort)[2], 0);
        String prefix = "";
        if(usedetail == 1){
          prefix = "detail_";
        }

        rs1.execute(value);
        while (rs1.next()) {

          SplitBean splitBean = new SplitBean();
          boolean isFillRight = fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, DurationTypeEnum.LEAVEBACK,key,result,datetimeFormatter);
          if(!isFillRight){
            return result;
          }
          doWorkSplitChain(splitBean, splitBeans);
        }


      }
    }
    return result;
  }

  @Deprecated
  private void reSplitLeaveBack(RecordSet rs1,
      List<SplitBean> splitBeans, String prefix, SplitBean splitBean, int requestId) throws Exception{
    WorkflowRequestComInfo requestComInfo = new WorkflowRequestComInfo();
    RecordSet rs2 = new RecordSet();
    //请假表单里的请假开始日期到结束日期的集合
    List<String> dateList = new ArrayList<>();
    //
    List<String> exceptList = new ArrayList<>();
    //
    List<Map<String,String>> splitList = new ArrayList<>();

    String fromDate = "";
    String toDate = "";
    String fromTime = "";
    String toTime = "";

    String leavefromDate = "";
    String leavetoDate = "";
    String leavefromTime = "";
    String leavetoTime = "";
    String leaveDB = "";

    String resourceId = Util.null2s(rs1.getString("resourceId"), "");
    fromDate = Util.null2s(rs1.getString(prefix+"fromDate"), "");
    toDate = Util.null2s(rs1.getString(prefix+"toDate"), "");
    fromTime = Util.null2s(rs1.getString(prefix+"fromTime"), "");
    toTime = Util.null2s(rs1.getString(prefix+"toTime"), "");

    leavefromDate = Util.null2s(rs1.getString(prefix+"leavefromDate"), "");
    leavefromTime = Util.null2s(rs1.getString(prefix+"leavefromTime"), "");
    leavetoDate = Util.null2s(rs1.getString(prefix+"leavetoDate"), "");
    leavetoTime = Util.null2s(rs1.getString(prefix+"leavetoTime"), "");
    leaveDB = Util.null2s(rs1.getString(prefix+"leaveduration"), "");
    String leaverequestid = Util.null2s(rs1.getString("leaverequestid"), "");
    String newLeaveType = Util.null2s(rs1.getString(prefix+"newLeaveType"), "");

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate localFromDate = LocalDate.parse(fromDate);
    LocalDate localToDate = LocalDate.parse(toDate);
    long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay();
    for (int i = 0; i <= betweenDays; i++) {
      LocalDate curLocalDate = localFromDate.plusDays(i);
      dateList.add(curLocalDate.format(dateFormatter));
    }

    String getLeaveSql = "select * from kq_flow_split_leave where requestid = "+leaverequestid+" and status = 0 "
        + "and newleavetype="+newLeaveType+" and fromdatedb='"+leavefromDate+"' and fromtimedb='"+leavefromTime+"' "
        + "and todatedb='"+leavetoDate+"' and totimedb='"+leavetoTime+"' and durationdb="+leaveDB+" and resourceId="+resourceId+" order by fromdate " ;
    rs2.executeQuery(getLeaveSql);

    //重新处理下这被拆分的两段请假数据
    for(int i = 0 ; i < 2 ; i++) {
      String reBuildFromDate = leavefromDate;
      String reBuildFromTime = leavefromTime;
      String reBuildtoDate = fromDate;
      String reBuildtoTime = fromTime;
      if (i == 1) {
        reBuildFromDate = toDate;
        reBuildFromTime = toTime;
        reBuildtoDate = leavetoDate;
        reBuildtoTime = leavetoTime;
      }

      splitBean.setFromDate(reBuildFromDate);
      splitBean.setFromTime(reBuildFromTime);
      splitBean.setToDate(reBuildtoDate);
      splitBean.setToTime(reBuildtoTime);

      splitBean.setFromdatedb(reBuildFromDate);
      splitBean.setFromtimedb(reBuildFromTime);
      splitBean.setTodatedb(reBuildtoDate);
      splitBean.setTotimedb(reBuildtoTime);
      splitBean.setDurationDB(leaveDB);

      splitBean.setRequestId(leaverequestid);
      splitBean.setLeavebackrequestid(requestId + "");
      splitBean.setWorkflowId(requestComInfo.getWorkflowId(leaverequestid));

      doWorkSplitChain(splitBean, splitBeans);
    }
  }


  /**
   * 补卡流程数据 生成签到签退数据并更新考勤报表
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQCardAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    String[] cardFields = KQAttFlowFieldsSetBiz.cardFields;

    KQFormatData kqFormatData = new KQFormatData();
    Map<String,String> result = new HashMap<>();
    RecordSet rs1 = new RecordSet();
    RecordSet rs2 = new RecordSet();

    String resourceId = "";
    String detail_scheduletime = "";
    String detail_signtype = "";
    String detail_signdate = "";
    String detail_signtime = "";

    String userId = "";
    String userType = "1";//默认给1
    String signType = "";
    String signDate = "";
    String signTime = "";
    String isInCom = "1";
//        String belongdate = "";

//        String serialid = "";
//        String worksection = "";
//        String belongtime = "";
    String signfrom = "";

    String signStatus = "";
//        String workdatesection = "";

    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String concort = "###" ;
        String key = me.getKey();
        String value = me.getValue();

        String wfId =  key.split(concort)[3] ;
        int usedetail =  Util.getIntValue(key.split(concort)[2], 0);
        String tableDetailName=  key.split(concort)[1] ;
        String tableName=  key.split(concort)[0] ;
        String idVal = "";
        String id = "dataId";
        if(usedetail == 1){
          id = "detailId";
        }
        rs1.execute(value);
        List<String> overtimeList = Lists.newArrayList();
        Map<String,List<String>> overtimeMap = Maps.newHashMap();
        while (rs1.next()) {
          idVal = Util.null2s(rs1.getString(id), "");
          String signSource = "card:|wfid|"+wfId+"|requestid|"+requestId+"|detailId|"+idVal;

          String f_resourceId = cardFields[0];
          String f_detail_signdate = cardFields[3];
          String f_detail_scheduletime = cardFields[4];
          String f_detail_signtype = cardFields[6];
          String f_detail_signtime = cardFields[7];
          resourceId = Util.null2s(rs1.getString(f_resourceId), "");
          detail_scheduletime = Util.null2s(rs1.getString(f_detail_scheduletime), "");
          detail_signtype = Util.null2s(rs1.getString(f_detail_signtype), "");
          detail_signdate = Util.null2s(rs1.getString(f_detail_signdate), "");
          detail_signtime = Util.null2s(rs1.getString(f_detail_signtime), "");
          userId = resourceId;

          signType = "0".equalsIgnoreCase(detail_signtype)?"1":"2";
          signDate = detail_signdate;
          signTime = detail_signtime+":00";
          signfrom = signSource;

          StringBuffer sql = new StringBuffer("insert into HrmScheduleSign(userId,userType,signType,signDate,signTime,isInCom,signfrom) values(")
              .append(userId).append(",'").append(userType).append("','")
              .append(signType).append("','").append(signDate).append("','")
              .append(signTime).append("','").append(isInCom).append("','")
              .append(signfrom).append("'").append(" )");
          boolean isOk = rs2.execute(sql.toString());

          if(!isOk){
            result.put("status", "-1");
            result.put("message", "补卡action保存失败：");
            return result;
          }
          kqLog.info("handleKQCardAction:userId:"+userId+":signDate:"+signDate);
          if(overtimeMap.containsKey(resourceId)){
            List<String> tmp_overtimeList = overtimeMap.get(resourceId);
            if(!tmp_overtimeList.contains(signDate)){
              tmp_overtimeList.add(signDate);
            }
          }else{
            if(!overtimeList.contains(signDate)){
              overtimeList.add(signDate);
            }
            overtimeMap.put(resourceId, overtimeList);
          }
        }

        List<KQTaskBean> tasks = new ArrayList<>();
        for(Map.Entry<String, List<String>> mme: overtimeMap.entrySet()){
          String resid = mme.getKey();
          List<String> overList = mme.getValue();
          for(String date : overList){
            SplitActionUtil.pushOverTimeTasks(date,date,resid,tasks);
            //考勤格式化
            new KQFormatBiz().formatDate(resid,date);
          }
        }
        if(!tasks.isEmpty()){
          KQQueue.writeTasks(tasks);
        }
      }
    }

    return result;
  }

  /**
   * 拆分异常流程数据 生成数据到splitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQOtherAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    Map<String,String> result = new HashMap<>();
    RecordSet rs1 = new RecordSet();

    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String key = me.getKey();
        String value = me.getValue();

        rs1.execute(value);
        while (rs1.next()) {
          SplitBean splitBean = new SplitBean();
          boolean isFillRight = fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, DurationTypeEnum.OTHER,key,result,datetimeFormatter);
          if(!isFillRight){
            return result;
          }

          doWorkSplitChain(splitBean, splitBeans);
        }

      }
    }
    return result;
  }

  /**
   * 拆分排班数据
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  private void handleKQShiftAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
    KQShiftscheduleBiz kqShiftscheduleBiz = new KQShiftscheduleBiz();

    RecordSet rs1 = new RecordSet();
    String detail_resourceId = "";
    String detail_fromDate = "";
    String detail_toDate = "";
    String detail_shift = "";
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    String[] shiftFields = KQAttFlowFieldsSetBiz.shiftDetailFields;
    kqLog.info("handleKQShiftAction: : sqlMap:"+sqlMap);

    if(!sqlMap.isEmpty()){
      KQFormatData kqFormatData = new KQFormatData();
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String concort = "###" ;
        String key = me.getKey();
        String value = me.getValue();

        String wfId =  key.split(concort)[3] ;
        int usedetail =  Util.getIntValue(key.split(concort)[2], 0);
        String tableDetailName=  key.split(concort)[1] ;
        String tableName=  key.split(concort)[0] ;
        String idVal = "";
        String id = "dataId";
        if(usedetail == 1){
          id = "detailId";
        }
        rs1.execute(value);
        while (rs1.next()) {
          idVal = Util.null2s(rs1.getString(id), "");

          String f_detail_resourceId = shiftFields[0];
          String f_detail_fromDate = shiftFields[1];
          String f_detail_toDate = shiftFields[2];
          String f_detail_shift = shiftFields[3];

          detail_resourceId = Util.null2s(rs1.getString(f_detail_resourceId), "");
          detail_fromDate = Util.null2s(rs1.getString(f_detail_fromDate), "");
          detail_toDate = Util.null2s(rs1.getString(f_detail_toDate), "");
          detail_shift = Util.null2s(rs1.getString(f_detail_shift), "");
          KQGroupEntity kQGroupEntity = kqGroupMemberComInfo.getUserKQGroupInfo(detail_resourceId,detail_fromDate,false);
          kqLog.info("handleKQShiftAction: : detail_resourceId:"+detail_resourceId+":detail_fromDate:"+detail_fromDate+":detail_toDate:"+detail_toDate+":detail_shift:"+detail_shift);

          if(kQGroupEntity == null){
            kqLog.info("handleKQShiftAction: kQGroupEntity is null : detail_resourceId:"+detail_resourceId+":detail_fromDate:"+detail_fromDate);
            continue;
          }
          kqLog.info("handleKQShiftAction: kQGroupEntity : kQGroupEntity:"+JSON.toJSON(kQGroupEntity)+":detail_resourceId:"+detail_resourceId
              +":detail_fromDate:"+detail_fromDate+":detail_toDate:"+detail_toDate+":detail_shift:"+detail_shift);

          String kqtype = kQGroupEntity.getKqtype();
          if ("2".equalsIgnoreCase(kqtype)) {
            kqShiftscheduleBiz.saveShiftschedule(detail_resourceId, detail_fromDate, detail_toDate, detail_shift,kQGroupEntity.getId());

            //排班流程 生成之后还需要格式化下对应人员下的考勤数据
            LocalDate fromLocal = LocalDate.parse(detail_fromDate);
            LocalDate toLocal = LocalDate.parse(detail_toDate);
            if(!toLocal.isBefore(fromLocal)){
              long betweenDays = toLocal.toEpochDay() - fromLocal.toEpochDay();
              for (int i = 0; i <= betweenDays; i++) {
                LocalDate curLocalDate = fromLocal.plusDays(i);
                String shiftDate = curLocalDate.format(dateFormatter);
                kqLog.info("handleKQShiftAction: formatDate : detail_resourceId:"+detail_resourceId+":shiftDate:"+shiftDate);
                new KQFormatBiz().formatDate(detail_resourceId, shiftDate);
              }
            }
          }else{
            kqLog.info("handleKQShiftAction: kqtype is not 2 : detail_resourceId:"+detail_resourceId+":detail_fromDate:"+detail_fromDate+":detail_toDate:"+detail_toDate+":kqtype:"+kqtype);
          }
        }
      }
    }
  }

  /**
   * 拆分加班数据 生成splitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQOvertimeAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    KQWorkTime kqWorkTime = new KQWorkTime();
    RecordSet rs1 = new RecordSet();
    Map<String,String> result = new HashMap<>();

    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String key = me.getKey();
        String value = me.getValue();
        String concort = "###" ;
        int usedetail =  Util.getIntValue(key.split(concort)[2], 0);
        String prefix = "";
        if(usedetail == 1){
          prefix = "detail_";
        }

        rs1.execute(value);
        while (rs1.next()) {

          String resourceId = Util.null2s(rs1.getString(prefix+"resourceId"), "");
          String fromDate = Util.null2s(rs1.getString(prefix+"fromDate"), "");
          WorkTimeEntity kqWorkTimeEntity = kqWorkTime.getWorkTime(resourceId,fromDate);
          if(kqWorkTimeEntity != null){
            String kqType = Util.null2String(kqWorkTimeEntity.getKQType());
            if("3".equalsIgnoreCase(kqType)){
              rs1.writeLog("自由班制不计算加班:resourceId:"+resourceId);
              continue;
            }
          }
          SplitBean splitBean = new SplitBean();
          boolean isFillRight = fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, DurationTypeEnum.OVERTIME,key,result,datetimeFormatter);
          if(!isFillRight){
            return result;
          }
          doNonWorkSplitChain(splitBean, splitBeans);
        }

      }
    }
    return result;
  }

  /**
   * 拆分公出数据 生成splitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQOutAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    RecordSet rs1 = new RecordSet();
    Map<String,String> result = new HashMap<>();

    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String key = me.getKey();
        String value = me.getValue();

        rs1.execute(value);
        while (rs1.next()) {
          SplitBean splitBean = new SplitBean();

          boolean isFillRight = fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, DurationTypeEnum.OUT,key,result,datetimeFormatter);
          if(!isFillRight){
            return result;
          }

          doWorkSplitChain(splitBean, splitBeans);
        }

      }
    }
    return result;
  }

  /**
   * 拆分出差数据 生成splitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQEvectionAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    Map<String,String> result = new HashMap<>();

    RecordSet rs1 = new RecordSet();
    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String key = me.getKey();
        String value = me.getValue();

        rs1.execute(value);
        while (rs1.next()) {

          SplitBean splitBean = new SplitBean();
          boolean isFillRight = fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, DurationTypeEnum.EVECTION,key,result,datetimeFormatter);
          if(!isFillRight){
            return result;
          }

          doWorkSplitChain(splitBean, splitBeans);
        }
      }
    }
    return result;
  }

  /**
   * 拆分请假数据 生成splitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQLeaveAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{
    RecordSet rs1 = new RecordSet();
    Map<String,String> result = new HashMap<>();

    if(!sqlMap.isEmpty()){
      for(Map.Entry<String,String> me : sqlMap.entrySet()){
        String key = me.getKey();
        String value = me.getValue();

        rs1.execute(value);
        while (rs1.next()) {
          SplitBean splitBean = new SplitBean();
          boolean isFillRight = fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, DurationTypeEnum.LEAVE,key,result,datetimeFormatter);
          if(!isFillRight){
            return result;
          }

          doWorkSplitChain(splitBean, splitBeans);
        }
      }
    }
    return result;
  }


  public boolean checkActionValidate(Map<String,String> result,String fromDate,String toDate,String fromTime,String toTime, DateTimeFormatter datetimeFormatter){

    boolean isVal = true;

    if(Util.null2String(fromDate,"").length() == 0  ||
        Util.null2String(toDate,"").length() == 0 ||
        Util.null2String(fromTime,"").length() == 0 ||
        Util.null2String(toTime,"").length() == 0){
      result.put("status", "-1");
      result.put("message", "日期时间不能为空");
      isVal = false;
      return isVal;
    }

    if((fromDate+" "+fromTime).length() != 16 || (toDate+" "+toTime).length() != 16){
      result.put("status", "-1");
      result.put("message", "日期时间格式有誤："+(fromDate+" "+fromTime)+":"+(toDate+" "+toTime));
      isVal = false;
      return isVal;
    }
    LocalDate localFromDate = LocalDate.parse(fromDate);
    LocalDate localToDate = LocalDate.parse(toDate);
    LocalDateTime localFromDateTime = LocalDateTime.parse(fromDate+" "+fromTime,datetimeFormatter);
    LocalDateTime localToDateTime = LocalDateTime.parse(toDate+" "+toTime,datetimeFormatter);

    if(localFromDateTime.isAfter(localToDateTime)){
      result.put("status", "-1");
      result.put("message", "开始日期时间不能大于结束日期时间");
      isVal = false;
      return isVal;
    }

    if (localFromDate.isAfter(localToDate)) {
      result.put("status", "-1");
      result.put("message", "日期区间有问题，开始日期大于结束日期");
      isVal = false;
      return isVal;
    }
    return isVal;

  }

  /**
   * 生成处理的sql
   * @param proc_set_id
   * @param usedetails
   * @param requestidInt
   * @return
   */
  public Map<String,String> handleSql(String proc_set_id,String usedetails,int requestidInt,int kqtype,Map<String, String> map) {

    HrmAttProcSetManager hrmAttProcSetManager= new HrmAttProcSetManager();
    Map<String,String> sqlMap = new HashMap<>();
    sqlMap = hrmAttProcSetManager.getSQLByField006Map(kqtype, map, false, true, proc_set_id,usedetails);

    return sqlMap;
  }

  /**
   * 计算工作时长拆分
   * @param splitBean
   * @param splitBeans
   * @throws Exception
   */
  public void doWorkSplitChain(SplitBean splitBean,List<SplitBean> splitBeans) throws Exception{

    WorkDurationChain hourUnitSplitChain = new WorkHourUnitSplitChain(splitBeans);
    WorkDurationChain dayUnitSplitChain = new WorkDayUnitSplitChain(splitBeans);
    WorkDurationChain halfUnitSplitChain = new WorkHalfUnitSplitChain(splitBeans);
    WorkDurationChain wholeUnitSplitChain = new WorkWholeUnitSplitChain(splitBeans);

    //设置执行链
    hourUnitSplitChain.setDurationChain(dayUnitSplitChain);
    dayUnitSplitChain.setDurationChain(halfUnitSplitChain);
    halfUnitSplitChain.setDurationChain(wholeUnitSplitChain);
    //把初始数据设置进去
    hourUnitSplitChain.handleDuration(splitBean);
  }

  /**
   * 计算非工作时长拆分
   * @param splitBean
   * @param splitBeans
   * @throws Exception
   */
  public void doNonWorkSplitChain(SplitBean splitBean,List<SplitBean> splitBeans) throws Exception{

    NonWorkDurationChain hourUnitSplitChain = new NonHourUnitSplitChain(splitBeans);
    NonWorkDurationChain dayUnitSplitChain = new NonDayUnitSplitChain(splitBeans);
    NonWorkDurationChain halfUnitSplitChain = new NonHalfUnitSplitChain(splitBeans);
    NonWorkDurationChain wholeUnitSplitChain = new NonWholeUnitSplitChain(splitBeans);

    //设置执行链
    hourUnitSplitChain.setDurationChain(dayUnitSplitChain);
    dayUnitSplitChain.setDurationChain(halfUnitSplitChain);
    halfUnitSplitChain.setDurationChain(wholeUnitSplitChain);
    //把初始数据设置进去
    hourUnitSplitChain.handleDuration(splitBean);

  }

  /**
   * 把通用的bean部分在这里进行填充
   * @param splitBean
   * @param rs1
   * @param requestId
   * @param rci
   * @param workflowId
   * @param durationTypeEnum
   * @param key
   * @param result
   * @param datetimeFormatter
   */
  public boolean fillSplitBean(SplitBean splitBean,RecordSet rs1,String requestId,ResourceComInfo rci,String workflowId,DurationTypeEnum durationTypeEnum,String key,Map<String,String> result,DateTimeFormatter datetimeFormatter){

    boolean isFillRight = true;
    String concort = "###" ;
    int usedetail =  Util.getIntValue(key.split(concort)[2], 0);
    String tableDetailName=  key.split(concort)[1] ;
    String tableName=  key.split(concort)[0] ;
    String prefix = "";
    String id = "dataId";
    if(usedetail == 1){
      prefix = "detail_";
      id = "detailId";
    }

    boolean isLeaveBack = false;
    if(durationTypeEnum == DurationTypeEnum.LEAVEBACK){
      isLeaveBack = true;
    }
    String resourceId = "";
    //查询到的requestid
    String requestId_rs = "";

    String idVal = Util.null2s(rs1.getString(id), "0");
    String fromDate = Util.null2s(rs1.getString(prefix+"fromDate"), "");
    String toDate = Util.null2s(rs1.getString(prefix+"toDate"), "");
    String fromTime = Util.null2s(rs1.getString(prefix+"fromTime"), "");
    String toTime = Util.null2s(rs1.getString(prefix+"toTime"), "");
    String durationDB = Util.null2s(rs1.getString(prefix+"duration"), "");
    if(durationTypeEnum == DurationTypeEnum.LEAVEBACK){
      resourceId = Util.null2s(rs1.getString("resourceId"), "");
    }else{
      resourceId = Util.null2s(rs1.getString(prefix+"resourceId"), "");
    }
    if(Util.getIntValue(requestId,0) <= 0){
      requestId_rs = Util.null2s(rs1.getString("requestId"), "0");
    }

    boolean isVal = checkActionValidate(result, fromDate, toDate, fromTime, toTime, datetimeFormatter);
    if(!isVal){
      isFillRight = false;
      return isFillRight;
    }
    if(isLeaveBack){
      LocalDateTime localFromDateTime = LocalDateTime.parse(fromDate+" "+fromTime,datetimeFormatter);
      LocalDateTime localToDateTime = LocalDateTime.parse(toDate+" "+toTime,datetimeFormatter);

      isFillRight = leaveBackCheck(rs1 ,datetimeFormatter,prefix,localFromDateTime,localToDateTime,result);
      if(!isFillRight){
        return isFillRight;
      }
    }

    if(usedetail == 1){
      splitBean.setDataId("0");
      splitBean.setDetailId(idVal);
      splitBean.setTablenamedb(tableDetailName);
    }else{
      splitBean.setDataId(idVal);
      splitBean.setDetailId("0");
      splitBean.setTablenamedb(tableName);
    }
    splitBean.setFromdatedb(fromDate);
    splitBean.setFromtimedb(fromTime);
    splitBean.setTodatedb(toDate);
    splitBean.setTotimedb(toTime);

    if(requestId_rs.length() > 0){
      WorkflowRequestComInfo workflowRequestComInfo = new WorkflowRequestComInfo();
      splitBean.setRequestId(requestId_rs);
      splitBean.setWorkflowId(workflowRequestComInfo.getWorkflowId(requestId_rs));
    }else{
      splitBean.setRequestId(requestId);
      splitBean.setWorkflowId(workflowId);
    }
    splitBean.setUsedetail(""+usedetail);
    splitBean.setResourceId(resourceId);
    splitBean.setSubcompanyid(Util.null2s(rci.getSubCompanyID(resourceId),"0"));
    splitBean.setDepartmentid(Util.null2s(rci.getDepartmentID(resourceId),"0"));
    splitBean.setJobtitle(Util.null2s(rci.getJobTitle(resourceId),"0"));
    splitBean.setFromDate(fromDate);
    splitBean.setFromTime(fromTime);
    splitBean.setToDate(toDate);
    splitBean.setToTime(toTime);
    splitBean.setDurationDB(durationDB);
    //默认记录的状态都为0
    splitBean.setStatus("0");
    if(isLeaveBack){
      splitBean.setDurationTypeEnum(DurationTypeEnum.LEAVEBACK);
    }else{
      splitBean.setDurationTypeEnum(durationTypeEnum);
    }
    switch (durationTypeEnum){
      case LEAVE:
        bean4Leave(prefix,rs1,splitBean);
        break;
      case EVECTION:
        bean4Evection(prefix,rs1,splitBean);
        break;
      case OUT:
        bean4Out(splitBean);
        break;
      case OVERTIME:
        bean4Overtime(splitBean);
        break;
      case LEAVEBACK:
        bean4LeaveBack(prefix,rs1,splitBean);
        break;
      case OTHER:
        bean4Other(prefix,rs1,splitBean);
        break;
      default:
        break;
    }
    String computingMode = splitBean.getComputingMode();
    String newLeaveType = splitBean.getNewLeaveType();
    if("2".equalsIgnoreCase(computingMode)){
      double oneDayHour = getOneDayHour(durationTypeEnum,newLeaveType);
      splitBean.setOneDayHour(oneDayHour);
    }
    return isFillRight;

  }

  private void bean4Other(String prefix, RecordSet rs1, SplitBean splitBean) {
    String minimumUnit = "1";
    String computingMode = "1";
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
  }

  /**
   * 销假流程特有的校验事件
   * @param rs1
   * @param datetimeFormatter
   * @param prefix
   * @param localFromDateTime
   * @param localToDateTime
   * @param result
   * @return
   */
  private boolean leaveBackCheck(RecordSet rs1, DateTimeFormatter datetimeFormatter, String prefix,
      LocalDateTime localFromDateTime, LocalDateTime localToDateTime,
      Map<String, String> result) {

    String leavefromDate = Util.null2s(rs1.getString(prefix+"leavefromDate"), "");
    String leavetoDate = Util.null2s(rs1.getString(prefix+"leavetoDate"), "");
    String leavefromTime = Util.null2s(rs1.getString(prefix+"leavefromTime"), "");
    String leavetoTime = Util.null2s(rs1.getString(prefix+"leavetoTime"), "");
    String leaveduration = Util.null2s(rs1.getString(prefix+"leaveduration"), "");

    LocalDateTime localleaveFromDateTime = LocalDateTime.parse(leavefromDate+" "+leavefromTime,datetimeFormatter);
    LocalDateTime localleaveToDateTime = LocalDateTime.parse(leavetoDate+" "+leavetoTime,datetimeFormatter);

    //销假区间要在请假区间内
    if((localFromDateTime.isAfter(localleaveFromDateTime) || localFromDateTime.isEqual(localleaveFromDateTime)) &&
        (localFromDateTime.isBefore(localleaveToDateTime) || localFromDateTime.isEqual(localleaveToDateTime)) &&
        (localToDateTime.isAfter(localleaveFromDateTime) || localToDateTime.isEqual(localleaveFromDateTime)) &&
        (localToDateTime.isBefore(localleaveToDateTime)  || localToDateTime.isEqual(localleaveToDateTime))){
      //这是满足条件的
    }else{
      //不在请假区间的
      result.put("status", "-1");
      result.put("message", "销假区间需要在请假日期时间范围内");
      return false;
    }
    return true;
  }

  /**
   * 销假流程和请假流程相似 单独需要赋值的数据
   * @param prefix
   * @param rs1
   * @param splitBean
   */
  private void bean4LeaveBack(String prefix, RecordSet rs1, SplitBean splitBean) {
    String leaverequestid = Util.null2s(rs1.getString("leaverequestid"), "");
    String newLeaveType = Util.null2s(rs1.getString(prefix+"newLeaveType"), "");
    String minimumUnit = Util.null2s(Util.null2String(KQLeaveRulesBiz.getMinimumUnit(newLeaveType)),"-1");
    String computingMode = Util.null2s(Util.null2String(KQLeaveRulesBiz.getComputingMode(newLeaveType)),"-1");

    splitBean.setLeavebackrequestid(leaverequestid);
    splitBean.setNewLeaveType(newLeaveType);
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
  }

  /**
   * 加班流程单独需要赋值的数据
   * @param splitBean
   */
  private void bean4Overtime(SplitBean splitBean) {
    String minimumUnit = Util.null2s(Util.null2String(KQOvertimeRulesBiz.getMinimumUnit()),"-1");
    String computingMode = "1";
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
  }

  /**
   * 公出流程单独需要赋值的数据
   * @param splitBean
   */
  private void bean4Out(SplitBean splitBean) {
    String minimumUnit = Util.null2s(Util.null2String(KQExitRulesBiz.getMinimumUnit()),"-1");
    String computingMode = Util.null2s(Util.null2String(KQExitRulesBiz.getComputingMode()),"-1");
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
  }

  /**
   * 出差流程单独需要赋值的数据
   * @param prefix
   * @param rs1
   * @param splitBean
   */
  private void bean4Evection(String prefix,RecordSet rs1, SplitBean splitBean) {
    String minimumUnit = Util.null2s(Util.null2String(KQTravelRulesBiz.getMinimumUnit()),"-1");
    String computingMode = Util.null2s(Util.null2String(KQTravelRulesBiz.getComputingMode()),"-1");
    String companion = Util.null2s(rs1.getString(prefix+"companion"), "");
    //设置同行人 这里拆分的时候并没有把同行人也拆分
    splitBean.setCompanion(companion);
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
  }

  /**
   * 请假流程单独需要赋值的数据
   * @param prefix
   * @param rs1
   * @param splitBean
   */
  private void bean4Leave(String prefix,RecordSet rs1, SplitBean splitBean) {
    String newLeaveType = Util.null2s(rs1.getString(prefix+"newLeaveType"), "");
    String minimumUnit = Util.null2s(Util.null2String(KQLeaveRulesBiz.getMinimumUnit(newLeaveType)),"-1");
    String computingMode = Util.null2s(Util.null2String(KQLeaveRulesBiz.getComputingMode(newLeaveType)),"-1");

    splitBean.setNewLeaveType(newLeaveType);
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
  }


  /**
   * 获取按照自然日计算的时候，按天/半天计算的时候一天对应的小时数
   * @param durationTypeEnum
   * @param newLeaveType
   * @return
   */
  public static double getOneDayHour(DurationTypeEnum durationTypeEnum,String newLeaveType){
    double oneDayHour = 0.0;
    //TODO KQLeaveRulesBiz.getHoursToDay如果单位是小时的时候取不到日折算时长
    switch (durationTypeEnum){
      case LEAVE:
        oneDayHour = Util.getDoubleValue(KQLeaveRulesBiz.getHoursToDay(newLeaveType), 0.0);
        break;
      case EVECTION:
        oneDayHour = Util.getDoubleValue(KQTravelRulesBiz.getHoursToDay(), 0.0);
        break;
      case OUT:
        oneDayHour = Util.getDoubleValue(KQExitRulesBiz.getHoursToDay(), 0.0);
        break;
      case OVERTIME:
        oneDayHour = KQOvertimeRulesBiz.getHoursToDay();
        break;
      case LEAVEBACK:
        oneDayHour = Util.getDoubleValue(KQLeaveRulesBiz.getHoursToDay(newLeaveType), 0.0);
        break;
      default:
    }
    return oneDayHour;
  }

  /**
   * 测试流程，删除测试数据的同时
   * 1、需要把冻结数据释放
   * 2、中间表数据清除
   * 3、格式化考勤报表
   * @param temprequestid
   * @param workflowid
   */
  public void delTest(int temprequestid, String workflowid) {
    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    RecordSet rs2 = new RecordSet();
    RecordSet rs3 = new RecordSet();
    try {

      if(Util.null2s(workflowid,"").length() == 0){
        return ;
      }

      String getkqType = "select * from kq_att_proc_set where field001=? ";
      rs.executeQuery(getkqType,workflowid);
      if(rs.next()){
        String tablename = "";
        int kqtype= Util.getIntValue(rs.getString("field006"),-1);
        if(kqtype == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.LEAVE.getTablename();
          String updateFreezeSql = "update KQ_ATT_VACATION set status=2 where requestId=?  ";
          boolean isUpdate = rs1.executeUpdate(updateFreezeSql,temprequestid);
          kqLog.info("KQFlowActiontBiz delTest:updateFreezeSql:"+updateFreezeSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate);
        }else if(kqtype == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.EVECTION.getTablename();
        }else if(kqtype == KqSplitFlowTypeEnum.OUT.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.OUT.getTablename();
        }else if(kqtype == KqSplitFlowTypeEnum.OVERTIME.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.OVERTIME.getTablename();
        }else if(kqtype == KqSplitFlowTypeEnum.SHIFT.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.SHIFT.getTablename();
        }else if(kqtype == KqSplitFlowTypeEnum.OTHER.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.OTHER.getTablename();
        }else if(kqtype == KqSplitFlowTypeEnum.CARD.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.CARD.getTablename();
        }else if(kqtype == KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()){
          tablename = KqSplitFlowTypeEnum.LEAVEBACK.getTablename();
        }else{
          new BaseBean().writeLog("删除测试流程异常，未找到考勤流程类型:workflowid:"+workflowid);
        }
        if(tablename.length() > 0){
          String delTableSql = "delete from "+tablename+"  where requestId= ?  ";
          boolean isUpdate = rs2.executeUpdate(delTableSql,temprequestid);
          kqLog.info("KQFlowActiontBiz delTest:delTableSql:"+delTableSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate);
          //如果有流程抵扣，删除对应流程抵扣的数据
          String delSql = "delete from kq_flow_deduct_card where requestid = ? ";
          isUpdate = rs3.executeUpdate(delSql,temprequestid);
          kqLog.info("KQFlowActiontBiz delTest:delSql:"+delSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate);
        }
      }
    }catch (Exception e){
      e.printStackTrace();
      rs.writeLog("KQFlowActiontBiz delTest:temprequestid:"+temprequestid+":workflowid:"+workflowid+":报错:"+e.getMessage());
    }
  }

}
